#include "queue.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


#define LOG_TAG    "mian"
#define LOG_LVL    ELOG_LVL_DEBUG
#include <elog.h>


// 队列初始化
queue_err queue_Init(queue_t *queue, uint32_t message_size, uint32_t message_max)
{
    if(queue == NULL)
    {
        return QUEUE_BUFFER_NULL;
    }

    queue->message_size = message_size;
    queue->message_max = message_max;
    queue->buf = (uint8_t *)malloc(queue->message_size * queue->message_max);
    queue->push_index = 0;
    queue->pop_index = 0;

    if(queue->buf == NULL)
    {
        return QUEUE_MALLOC_FAILURE;
    }

    return QUEUE_OK;
}


// 队列释放
queue_err queue_DeInit(queue_t *queue)
{
    if(queue == NULL)
    {
        return QUEUE_BUFFER_NULL;
    }

    free(queue->buf);
    queue->buf = NULL;
    queue->message_size = 0;
    queue->message_max = 0;
    queue->push_index = 0;
    queue->pop_index = 0;

    return QUEUE_OK;
}


// 获取队列中消息数量
uint32_t queue_get_cnt(queue_t *queue)
{
    if(queue == NULL)
    {
        return QUEUE_BUFFER_NULL;
    }

    return queue->cnt;
}


// 队列入队
queue_err queue_push(queue_t *queue,void *message)
{

    if(queue == NULL || message == NULL)
    {
        return QUEUE_BUFFER_NULL;
    }

    if(queue->cnt == queue->message_max) // 缓冲区满
    {
        return QUEUE_BUFFER_OVERFLOW;
    }

    memcpy(queue->buf + queue->push_index * queue->message_size, message, queue->message_size);
    if(queue->push_index == queue->message_max)
        queue->push_index = 0;
    else
        queue->push_index++;
    queue->cnt++;
    
    return QUEUE_OK;
}


// 队列出队
queue_err queue_pop(queue_t *queue,void *message)
{
    if(queue == NULL || message == NULL)
    {
        return QUEUE_BUFFER_NULL;
    }

    if(queue->cnt == 0) // 缓冲区空
    {
        return QUEUE_BUFFER_NULL;
    }

    memcpy(message, queue->buf + queue->pop_index * queue->message_size, queue->message_size);
    if(queue->pop_index == queue->message_max)
        queue->pop_index = 0;
    else
        queue->pop_index++;
    queue->cnt--;

    return QUEUE_OK;
}
